package com.study.util.desensitization.serializer;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.study.util.desensitization.Symbol;
import com.study.util.desensitization.annotation.Desensitize;
import com.study.util.desensitization.deserializer.Desensitization;
import com.study.util.desensitization.deserializer.DesensitizationFactory;
import com.study.util.desensitization.deserializer.StringDesensitization;

/**
 * 脱敏序列化器
 * 
 * @author chenk
 *
 */
public class ObjectDesensitizeSerializer extends StdSerializer<Object> implements ContextualSerializer {

	private transient Desensitization<Object> desensitization;

	protected ObjectDesensitizeSerializer() {
		super(Object.class);
	}

	@Override
	public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
			throws JsonMappingException {
		Desensitize annotation = property.getAnnotation(Desensitize.class);
		return createContextual(annotation.desensitization());
	}

	@SuppressWarnings("unchecked")
	private JsonSerializer<?> createContextual(Class<? extends Desensitization<?>> clazz) {
		ObjectDesensitizeSerializer serializer = new ObjectDesensitizeSerializer();
		if (clazz != StringDesensitization.class) {
			serializer.setDesensitization((Desensitization<Object>) DesensitizationFactory.getDesensitization(clazz));
		}
		return serializer;
	}

	@Override
	public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
		Desensitization<Object> objectDesensitization = getDesensitization();
		if (objectDesensitization != null) {
			try {
				gen.writeObject(objectDesensitization.desensitize(value));
			} catch (IOException e) {
				gen.writeObject(value);
			}
		} else if (value instanceof String) {
			gen.writeString(Symbol.getSymbol(((String) value).length(), Symbol.STAR));
		} else {
			gen.writeObject(value);
		}
	}

	public Desensitization<Object> getDesensitization() {
		return desensitization;
	}

	public void setDesensitization(Desensitization<Object> desensitization) {
		this.desensitization = desensitization;
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 5728582656198601476L;

}
